package bind

import (
	"bytes"
	"fmt"
	"gitee.com/gopher2011/gin/internal/json"
	"io"
	"net/http"
)

// 对于绑定json格式的请求参数，不光使用了标准库中的 encoding/json 还引用了第三方库中json https://github.com/json-iterator/go

// EnableDecoderUseNumber 用于在JSON Decoder实例上调用UseNumber方法。
//  UseNumber使解码器将数字解组到接口{}中，作为数字而不是float64。
var EnableDecoderUseNumber = false

// EnableDecoderDisallowUnknownFields 用于在JSON Decoder实例上调用DisallowUnknownFields方法。
//  当目标是结构并且输入包含与目标中任何未忽略的导出字段都不匹配的对象键时，DisallowUnknownFields会导致解码器返回错误。
var EnableDecoderDisallowUnknownFields = false

type jsonBinding struct{}

func (jsonBinding) Name() string {
	return "json"
}

func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
	if req == nil || req.Body == nil {
		return fmt.Errorf("invalid request")
	}
	return decodeJSON(req.Body, obj)
}

func (jsonBinding) BindBody(body []byte, obj interface{}) error {
	return decodeJSON(bytes.NewReader(body), obj)
}

func decodeJSON(r io.Reader, obj interface{}) error {
	decoder := json.NewDecoder(r)
	if EnableDecoderUseNumber {
		decoder.UseNumber()
	}
	if EnableDecoderDisallowUnknownFields {
		decoder.DisallowUnknownFields()
	}
	if err := decoder.Decode(obj); err != nil {
		return err
	}
	return validate(obj)
}
